home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / math / fixfloa2 / fixfloat.asm < prev    next >
Assembly Source File  |  1995-03-29  |  34KB  |  1,680 lines

  1. .386
  2.  
  3.  
  4. _TEXT   SEGMENT BYTE PUBLIC USE32 'CODE'
  5.  
  6.     ASSUME  cs:_TEXT
  7.  
  8.  
  9.  
  10. extern _rand_table:dword
  11.  
  12. extern _sin_table:word
  13. extern _asin_table:word
  14.  
  15. extern _tan_table1:dword
  16. extern _tan_table3:dword
  17. extern _tan_table4:dword
  18.  
  19. extern _atan_table1:word
  20. extern _atan_table2:word
  21. extern _atan_table3:word
  22. extern _atan_table4:word
  23.  
  24. extern _log2_table:word
  25. extern _exp2_table:word
  26. extern _sqrt_table:word
  27.  
  28.  
  29. public   _rnd1
  30. public   _rnd2
  31. public   _rnd3
  32.  
  33. _rnd1         dd     193
  34. _rnd2         dd     0
  35. _rnd3         dd     122231
  36.  
  37.  
  38.  
  39. public rand32_
  40.  
  41. rand32_ proc near
  42.          push    edx
  43.  
  44.          mov     edx,[_rnd3]
  45.          mov     eax,[_rnd1]
  46.          and     edx,03FFh
  47.  
  48.          mul     edx
  49.          inc     [_rnd2]
  50.          mov     edx,[_rnd2]
  51.          and     edx,16383
  52.          jne     r_a
  53.  
  54.          push    edx
  55.          shr     edx,14
  56.          add     [_rnd3],3
  57.          and     edx,16383
  58.          add     eax,[_rand_table+edx]
  59.          add     [_rand_table+edx],1239876
  60.          pop     edx
  61.  
  62. r_a:     add     eax,[_rand_table+edx]
  63.  
  64.          pop     edx
  65.          mov     [_rnd1],eax
  66.          ret
  67.  
  68. rand32_ endp
  69.  
  70. ; eax - desired two pow interval
  71. ; edx - desired interval
  72.  
  73. public randpowint_
  74.  
  75. randpowint_   proc near
  76.  
  77.          push    ebx
  78.          mov     ebx,eax
  79.  
  80. get_another:
  81. ; unrolling starts
  82.           push    edx
  83.           mov     edx,[_rnd3]
  84.           mov     eax,[_rnd1]
  85.           and     edx,03FFh
  86.  
  87.           mul     edx
  88.           inc     [_rnd2]
  89.           mov     edx,[_rnd2]
  90.           and     edx,16383
  91.           jne     pir_a
  92.  
  93.           push    edx
  94.           shr     edx,14
  95.           add     [_rnd3],3
  96.           and     edx,16383
  97.           add     eax,[_rand_table+edx]
  98.           add     [_rand_table+edx],1239876
  99.           pop     edx
  100.  
  101. pir_a:    add     eax,[_rand_table+edx]
  102.           pop     edx
  103.           mov     [_rnd1],eax
  104. ; unrolling stops
  105.  
  106.          and     eax,ebx
  107.          cmp     eax,edx
  108.          jae     get_another
  109.  
  110.          pop     ebx
  111.  
  112.          ret
  113.  
  114.  
  115. randpowint_   endp
  116.  
  117.  
  118. public randinter_
  119.  
  120. randinter_ proc near
  121.           push   edx
  122.           push   ecx
  123.           push   eax
  124.  
  125. frl00:    xor    ecx,ecx
  126.           cmp    eax,010000h
  127.           jb     frl0
  128.           shr    eax,16
  129.           add    cl,16
  130.  
  131. frl0:     cmp    eax,0100h
  132.           jb     frl1
  133.           shr    eax,8
  134.           add    cl,8
  135.  
  136. frl1:     cmp    eax,010h
  137.           jb     frl2
  138.           shr    eax,4
  139.           add    cl,4
  140.  
  141. frl2:     cmp    eax,04h
  142.           jb     frl3
  143.           shr    eax,2
  144.           add    cl,2
  145.  
  146. frl3:     cmp    eax,2
  147.           jb     frl4
  148.           inc    ecx
  149.  
  150. frl4:     inc    cl
  151.           mov    edx,1
  152.           shl    edx,cl
  153.           pop    ecx
  154.           dec    edx        ; eax now holding 2pow interval
  155.  
  156. gget_another:
  157.  
  158. ; unrolling starts
  159.           push    edx
  160.           mov     edx,[_rnd3]
  161.           mov     eax,[_rnd1]
  162.           and     edx,03FFh
  163.  
  164.           mul     edx
  165.           inc     [_rnd2]
  166.           mov     edx,[_rnd2]
  167.           and     edx,16383
  168.           jne     ir_a
  169.  
  170.           push    edx
  171.           shr     edx,14
  172.           add     [_rnd3],3
  173.           and     edx,16383
  174.           add     eax,[_rand_table+edx]
  175.           add     [_rand_table+edx],1239876
  176.           pop     edx
  177.  
  178. ir_a:     add     eax,[_rand_table+edx]
  179.           pop     edx
  180.           mov     [_rnd1],eax
  181. ; unrolling stops
  182.  
  183.           and     eax,edx
  184.           cmp     eax,ecx
  185.           jae     gget_another
  186.  
  187.           pop     ecx
  188.           pop     edx
  189.           ret
  190.  
  191. randinter_ endp
  192.  
  193.  
  194.  
  195. public ffsmul_
  196.  
  197. ; eax - contains fixfloat 1
  198. ; edx - contains fixfloat 2
  199. ; routine affects edx due to 64 bit multiplication
  200.  
  201. ffsmul_ proc near
  202.           imul   edx
  203.           shrd   eax,edx,16
  204.           ret
  205. ffsmul_ endp
  206.  
  207.  
  208. public ffsdiv_
  209.  
  210. ; eax contains denominator (Above division line)
  211. ; edx contains nominator   (Below division line)
  212.  
  213. ffsdiv_ proc near
  214.           
  215.           push   edx
  216.           push   ecx
  217.           push   ebx
  218.  
  219.           or     eax,eax
  220.           mov    ecx,edx
  221.           mov    bl,0
  222.           jns    fsd_1
  223.  
  224.           neg    eax
  225.           inc    bl
  226.  
  227. fsd_1:    or     ecx,ecx
  228.           mov    edx,eax
  229.           jns    fsd_2
  230.  
  231.           neg    ecx
  232.           inc    bl
  233.  
  234. fsd_2:    shr    edx,16
  235.           shl    eax,16
  236.           cmp    edx,ecx
  237.           jae    div_by_0
  238.  
  239.           div    ecx
  240.           test   bl,1
  241.           pop    ebx
  242.           pop    ecx
  243.           pop    edx
  244.           je     fsd_3
  245.  
  246.           neg    eax
  247. fsd_3:    ret
  248.  
  249. div_by_0: test   bl,1
  250.           pop    ebx
  251.           pop    ecx
  252.           pop    edx
  253.           jne    dbz1
  254.           mov    eax,07FFFFFFFh
  255.           ret
  256.  
  257. dbz1:     mov    eax,080000000h
  258.           ret
  259.  
  260. ffsdiv_ endp
  261.  
  262.  
  263. public ffmul_
  264.  
  265. ; eax - contains fixfloat 1
  266. ; edx - contains fixfloat 2
  267. ; routine affects edx due to 64 bit multiplication
  268.  
  269. ffmul_ proc near
  270.  
  271.           mul    edx
  272.           shrd   eax,edx,16
  273.           ret
  274.  
  275. ffmul_ endp
  276.  
  277.  
  278. public ffdiv_
  279.  
  280. ; eax contains denominator (Above division line)
  281. ; edx contains nominator   (Below division line)
  282.  
  283. ffdiv_ proc near
  284.  
  285.           push   edx
  286.           push   ecx
  287.           mov    ecx,edx
  288.           mov    edx,eax
  289.           shl    eax,16
  290.           shr    edx,16
  291.           cmp    edx,ecx
  292.           jae    div_by_00
  293.  
  294.           div    ecx
  295.           pop    ecx
  296.           pop    edx
  297.           ret
  298.  
  299. div_by_00:
  300.           pop    ecx
  301.           pop    edx
  302.           mov    eax,0FFFFFFFFh
  303.           ret
  304.  
  305. ffdiv_ endp
  306.  
  307.  
  308.  
  309. public ffsin_
  310. public ffcos_
  311. ffcos_:
  312.           add    eax,04000h     ; that's all there is to it !
  313.  
  314. ffsin_ proc near
  315.  
  316.           push   ebx
  317.           test   eax,08000h
  318.           setne  bl
  319.           and    eax,07FFFh
  320.           cmp    eax,04000h
  321.           jb     fsn1
  322.           xor    eax,07FFFh
  323. fsn1:     shr    eax,2          ; increased resolution 4 times
  324.           mov    ax,[_sin_table+eax*2]
  325.           or     bl,bl
  326.           je     ffsn2
  327.           neg    eax
  328. ffsn2:    pop    ebx
  329.           ret
  330.  
  331. ffsin_     endp
  332.  
  333. public ffasin_
  334. ffasin_ proc near
  335.  
  336.           push   ebx
  337.           or     eax,eax
  338.           mov    bl,0
  339.           jns    fasn2
  340.           neg    eax
  341.           inc    ebx
  342.  
  343. fasn2:    and    eax,0FFFFh
  344.           shr    eax,4
  345.           mov    ax,[_asin_table+eax*2]
  346.           or     bl,bl
  347.           je     fasn1
  348.           neg    eax
  349. fasn1:    pop    ebx
  350.           ret
  351.  
  352. ffasin_ endp
  353.  
  354. public ffacos_
  355. ffacos_ proc near
  356.  
  357.           push   ebx
  358.           or     eax,eax
  359.           mov    bl,0
  360.           jns    facn2
  361.           neg    eax
  362.           inc    ebx
  363.  
  364. facn2:    and    eax,0FFFFh
  365.           shr    eax,4
  366.           mov    ax,[_asin_table+eax*2]
  367.           or     bl,bl
  368.           je     facn1
  369.           neg    eax
  370. facn1:    pop    ebx
  371.           sub    eax,04000h
  372.           neg    eax
  373.           ret
  374.  
  375. ffacos_ endp
  376.  
  377.  
  378. public fftan_
  379. fftan_ proc near
  380.  
  381.           push   ebx
  382.  
  383.           test   eax,4000h
  384.           mov    bl,0
  385.           je     ftn1
  386.           test   eax,3FFFh
  387.           jne    ftn01
  388.           mov    eax,030000000h ; almost infinity
  389.           pop    ebx
  390.           ret
  391.  
  392. ftn01:    neg    eax
  393.           inc    bl
  394.  
  395. ftn1:     and    eax,03FFFh
  396.           cmp    eax,03C00h
  397.           jae    ftn3
  398.  
  399.           shr    eax,4          ; lowest tan interval
  400.           or     bl,bl
  401.           mov    eax,[_tan_table1+eax*4]
  402.           je     ftn11
  403.           neg    eax
  404. ftn11:    pop    ebx
  405.           ret
  406.  
  407.  
  408. ftn3:     cmp    eax,03F00h
  409.           jae    ftn4
  410.  
  411.           and    eax,03fch
  412.           or     bl,bl
  413.           mov    eax,[_tan_table3+eax]
  414.           je     ftn31
  415.           neg    eax
  416. ftn31:    pop    ebx
  417.           ret
  418.  
  419. ftn4:     and    eax,0FFh
  420.           or     bl,bl
  421.           mov    eax,[_tan_table4+eax*4]
  422.           je     ftn41
  423.           neg    eax
  424. ftn41:    pop    ebx
  425.           ret
  426.  
  427. fftan_ endp
  428.  
  429.  
  430. public ffatan_
  431.  
  432. ffatan_ proc near
  433.  
  434.           push   ebx
  435.           or     eax,eax
  436.           mov    bl,0
  437.           jns    fat0
  438.           neg    eax
  439.           inc    ebx
  440.  
  441. fat0:     cmp    eax,040000h
  442.           jae    fat1
  443.           shr    eax,8
  444.           or     bl,bl
  445.           mov    ax,[_atan_table1+eax*2]
  446.           je     fat01
  447.           neg    eax
  448. fat01:    pop    ebx
  449.           ret
  450.  
  451. fat1:     cmp    eax,0100000h
  452.           jae    fat2
  453.           shr    eax,12
  454.           or     bl,bl
  455.           mov    ax,[_atan_table2+eax*2]
  456.           je     fat11
  457.           neg    eax
  458. fat11:    pop    ebx
  459.           ret
  460.  
  461. fat2:     cmp    eax,02000000h ; 512.0
  462.           jae    fat3
  463.           shr    eax,17
  464.           or     bl,bl
  465.           mov    ax,[_atan_table3+eax*2]
  466.           je     fat21
  467.           neg    eax
  468. fat21:    pop    ebx
  469.           ret
  470.  
  471. fat3:     cmp    eax,020000000h ; 8192.0
  472.           jae    fat4
  473.           shr    eax,21
  474.           or     bl,bl
  475.           mov    ax,[_atan_table4+eax*2]
  476.           je     fat31
  477.           neg    eax
  478. fat31:    pop    ebx
  479.           ret
  480.  
  481. fat4:     or     bl,bl
  482.           mov    eax,03FFFh ; almost 90 degrees
  483.           jns    fat31
  484.           neg    eax
  485.           jmp    fat31
  486.  
  487. ffatan_ endp
  488.  
  489.  
  490. public fflog2_
  491.  
  492. fflog2_ proc near
  493.  
  494.           push   ecx
  495.           push   ebx
  496.  
  497.           or     eax,eax
  498.           mov    ebx,eax
  499.           jne    ffl00
  500.           mov    eax,80000000h       ; approx -infinity
  501.           pop    ebx
  502.           pop    ecx
  503.           ret
  504.  
  505. ffl00:    xor    ecx,ecx
  506.           cmp    eax,010000h
  507.           jb     ffl0
  508.           shr    eax,16
  509.           add    cl,16
  510.  
  511. ffl0:     cmp    eax,0100h
  512.           jb     ffl1
  513.           shr    eax,8
  514.           add    cl,8
  515.  
  516. ffl1:     cmp    eax,010h
  517.           jb     ffl2
  518.           shr    eax,4
  519.           add    cl,4
  520.  
  521. ffl2:     cmp    eax,04h
  522.           jb     ffl3
  523.           shr    eax,2
  524.           add    cl,2
  525.  
  526. ffl3:     cmp    eax,2
  527.           jb     ffl4
  528.           inc    ecx
  529.  
  530. ffl4:     mov    eax,ebx
  531.           mov    bl,cl
  532.           sub    cl,12
  533.           js     ffl5
  534.           shr    eax,cl
  535.           jmp    ffl6
  536.  
  537. ffl5:     neg    cl
  538.           shl    eax,cl
  539.  
  540. ffl6:     sub    eax,01000h
  541.           sub    bl,16
  542.           mov    cx,[_log2_table+eax*2]
  543.           movsx  eax,bl
  544.           pop    ebx
  545.           shl    eax,16
  546.           mov    ax,cx
  547.  
  548.           pop    ecx
  549.           ret
  550.  
  551. fflog2_ endp
  552.  
  553. public ffexp2_
  554.  
  555. ffexp2_ proc near
  556. ;          test   eax,0FFFFh
  557.           push   ecx
  558.           mov    ecx,eax
  559. ;          je     fenodec
  560.  
  561.           shr    eax,4
  562.           sar    ecx,16
  563.           js     fe1
  564.           and    eax,0FFFh
  565.           mov    ax,[_exp2_table+eax*2]
  566.           add    eax,10000h
  567.           shl    eax,cl
  568.           pop    ecx
  569.           ret
  570.  
  571. fe1:      and    eax,0FFFh
  572.           neg    cl
  573.           mov    ax,[_exp2_table+eax*2]
  574.           add    eax,10000h
  575.           shr    eax,cl
  576.           pop    ecx
  577.           ret
  578.  
  579. fenodec:  sar    ecx,16
  580.           mov    eax,1
  581.           add    ecx,16
  582.           shl    eax,cl
  583.           pop    ecx
  584.           ret
  585.  
  586. ffexp2_ endp
  587.  
  588. public ffpow_
  589.  
  590. ffpow_ proc near               ; neat procedure eh?
  591.  
  592.           call   fflog2_
  593.           call   ffsmul_
  594.           call   ffexp2_
  595.           ret
  596.  
  597. ffpow_ endp
  598.  
  599. public ffsqrt_
  600.  
  601. ffsqrt_ proc near
  602.  
  603.           push ecx
  604.           push ebx
  605.  
  606.           or     eax,eax
  607.           mov    ebx,eax
  608.           jne    ffs00
  609.           mov    eax,0h       ; sqrt 0 = 0
  610.           pop    ebx
  611.           pop    ecx
  612.           ret
  613.  
  614. ffs00:    xor    ecx,ecx
  615.           cmp    eax,010000h
  616.           jb     ffs0
  617.           shr    eax,16
  618.           add    cl,16
  619.  
  620. ffs0:     cmp    eax,0100h
  621.           jb     ffs1
  622.           shr    eax,8
  623.           add    cl,8
  624.  
  625. ffs1:     cmp    eax,010h
  626.           jb     ffs2
  627.           shr    eax,4
  628.           add    cl,4
  629.  
  630. ffs2:     cmp    eax,04h
  631.           jb     ffs3
  632.           shr    eax,2
  633.           add    cl,2
  634.  
  635. ffs3:     cmp    eax,2
  636.           jb     ffs4
  637.           inc    ecx
  638.  
  639. ffs4:     mov    eax,ebx
  640.           sub    cl,15
  641.           test   cl,1
  642.           je     ffs5
  643.           inc    cl
  644.  
  645. ffs5:     mov    bl,cl
  646.           add    cl,4
  647.           jns    ffs6
  648.           neg    cl
  649.           shl    eax,cl
  650.           jmp    ffs7
  651.  
  652. ffs6:     shr    eax,cl
  653.  
  654. ffs7:     sar    bl,1
  655.           mov    ax,[_sqrt_table+eax*2]
  656.           or     bl,bl
  657.           mov    cl,bl
  658.           js     ffs8
  659.           shl    eax,cl
  660.  
  661.           pop    ebx
  662.           pop    ecx
  663.           ret
  664.  
  665. ffs8:     neg    cl
  666.           pop    ebx
  667.           shr    eax,cl
  668.           pop    ecx
  669.           ret
  670.  
  671. ffsqrt_ endp
  672.  
  673.  
  674. public fftrihyp_
  675.  
  676. fftrihyp_ proc near
  677.  
  678.           push   ecx
  679.           push   ebx
  680. fthp0:    mov    ebx,edx      ;            2
  681.           imul   eax          ; edx:eax - a
  682.           mov    ecx,edx
  683. fthp1:    xchg   eax,ebx      ; ecx:ebx - a
  684.           imul   eax
  685.           add    ebx,eax      ;            2  2
  686.           pop    eax
  687.           adc    ecx,edx      ; edx:eax - a +b
  688.           push   eax
  689. fthp11:   imul    eax
  690.           add    eax,ebx
  691.           adc    edx,ecx
  692.  
  693.           je     t_hi_reg_zero
  694.  
  695. ;          bsr    ecx,edx
  696.  
  697. ; code from here
  698.           push   edx
  699.           xor    ecx,ecx
  700.           cmp    edx,010000h
  701.           jb     bsr00
  702.           shr    edx,16
  703.           add    cl,16
  704.  
  705. bsr00:    cmp    edx,0100h
  706.           jb     bsr01
  707.           shr    edx,8
  708.           add    cl,8
  709.  
  710. bsr01:    cmp    edx,010h
  711.           jb     bsr02
  712.           shr    edx,4
  713.           add    cl,4
  714.  
  715. bsr02:    cmp    edx,04h
  716.           jb     bsr03
  717.           shr    edx,2
  718.           add    cl,2
  719.  
  720. bsr03:    cmp    edx,2
  721.           jb     bsr04
  722.           inc    ecx
  723.  
  724. bsr04:    pop    edx
  725. ; to here replaces bsr with a factor 2.5 speed gain
  726.  
  727.           add    cl,17
  728.           test   cl,1
  729.           je     fthp2
  730.           inc    ecx
  731. fthp2:    mov    ebx,ecx
  732.           cmp    cl,020h
  733.           jae    fthp20
  734.           shrd   eax,edx,cl
  735.           jmp    t_ready_to_root
  736.  
  737. fthp20:   sub    cl,020h
  738.           mov    eax,edx      ; 20 shifts
  739.           shr    eax,cl
  740.           jmp    t_ready_to_root
  741.  
  742.  
  743. t_hi_reg_zero:
  744. ;          bsr    ecx,eax
  745. ; code from here
  746.           push   eax
  747.           xor    ecx,ecx
  748.           cmp    eax,010000h
  749.           jb     bsr10
  750.           shr    eax,16
  751.           add    cl,16
  752.  
  753. bsr10:    cmp    eax,0100h
  754.           jb     bsr11
  755.           shr    eax,8
  756.           add    cl,8
  757.  
  758. bsr11:    cmp    eax,010h
  759.           jb     bsr12
  760.           shr    eax,4
  761.           add    cl,4
  762.  
  763. bsr12:    cmp    eax,04h
  764.           jb     bsr13
  765.           shr    eax,2
  766.           add    cl,2
  767.  
  768. bsr13:    cmp    eax,2
  769.           jb     bsr14
  770.           inc    ecx
  771.  
  772. bsr14:    pop    eax
  773. ; to here replaces bsr with a factor 2.5 speed gain
  774.  
  775.           sub    cl,15
  776.           test   cl,1
  777.           je     thrz1
  778.           inc    ecx
  779. thrz1:    mov    ebx,ecx
  780.           or     ecx,ecx
  781.           js     thrz2
  782.           shr    eax,cl
  783.           jmp    t_ready_to_root
  784.  
  785. thrz2:    neg    ecx
  786.           shl    eax,cl
  787.  
  788. t_ready_to_root:
  789.           shr    eax,4        ;
  790.           mov    ecx,ebx
  791.           and    eax,0fffh
  792.           sub    cl,16
  793.           mov    ax,[_sqrt_table+eax*2]
  794.           sar    cl,1
  795.           js     trtr1
  796.           shl    eax,cl
  797.           pop    ebx
  798.           pop    ecx
  799.           ret
  800.  
  801. trtr1:    neg    cl
  802.           shr    eax,cl
  803.           pop    ebx
  804.           pop    ecx
  805.           ret
  806.  
  807. fftrihyp_ endp
  808.  
  809.  
  810. public ffhyp_
  811.  
  812. ffhyp_ proc near
  813.  
  814.           push   ecx
  815.           push   ebx
  816.  
  817. fhp0:     mov    ebx,edx      ;            2
  818.           imul   eax          ; edx:eax - a
  819.           mov    ecx,edx
  820.                               ;            2
  821. fhp1:     xchg   eax,ebx      ; ecx:ebx - a
  822.           imul   eax
  823.           add    eax,ebx      ;            2  2
  824.           adc    edx,ecx      ; edx:eax - a + b
  825.  
  826.           je     hi_reg_zero
  827.  
  828. ;          bsr    ecx,edx
  829. ; code from here
  830.           push   edx
  831.           xor    ecx,ecx
  832.           cmp    edx,010000h
  833.           jb     bsr20
  834.           shr    edx,16
  835.           add    cl,16
  836.  
  837. bsr20:    cmp    edx,0100h
  838.           jb     bsr21
  839.           shr    edx,8
  840.           add    cl,8
  841.  
  842. bsr21:    cmp    edx,010h
  843.           jb     bsr22
  844.           shr    edx,4
  845.           add    cl,4
  846.  
  847. bsr22:    cmp    edx,04h
  848.           jb     bsr23
  849.           shr    edx,2
  850.           add    cl,2
  851.  
  852. bsr23:    cmp    edx,2
  853.           jb     bsr24
  854.           inc    ecx
  855.  
  856. bsr24:    pop    edx
  857. ; to here replaces bsr with a factor 2.5 speed gain
  858.  
  859.  
  860.           add    cl,17
  861.           test   cl,1
  862.           je     fhp2
  863.           inc    ecx
  864. fhp2:     mov    ebx,ecx
  865.           cmp    cl,020h
  866.           jae    fhp20
  867.           shrd   eax,edx,cl
  868.           jmp    ready_to_root
  869.  
  870. fhp20:    sub    cl,020h
  871.           mov    eax,edx      ; 020h shifts
  872.           shr    eax,cl
  873.           jmp    ready_to_root
  874.  
  875.  
  876. hi_reg_zero:
  877. ;          bsr    ecx,eax
  878. ; code from here
  879.           push   eax
  880.           xor    ecx,ecx
  881.           cmp    eax,010000h
  882.           jb     bsr30
  883.           shr    eax,16
  884.           add    cl,16
  885.  
  886. bsr30:    cmp    eax,0100h
  887.           jb     bsr31
  888.           shr    eax,8
  889.           add    cl,8
  890.  
  891. bsr31:    cmp    eax,010h
  892.           jb     bsr32
  893.           shr    eax,4
  894.           add    cl,4
  895.  
  896. bsr32:    cmp    eax,04h
  897.           jb     bsr33
  898.           shr    eax,2
  899.           add    cl,2
  900.  
  901. bsr33:    cmp    eax,2
  902.           jb     bsr34
  903.           inc    ecx
  904.  
  905. bsr34:    pop    eax
  906. ; to here replaces bsr with a factor 2.5 speed gain
  907.  
  908.  
  909.           sub    cl,15
  910.           test   cl,1
  911.           je     hrz1
  912.           inc    ecx
  913. hrz1:     mov    ebx,ecx
  914.           or     ecx,ecx
  915.           js     hrz2
  916.           shr    eax,cl
  917.           jmp    ready_to_root
  918.  
  919. hrz2:     neg    ecx
  920.           shl    eax,cl
  921.  
  922. ready_to_root:
  923.           shr    eax,4        ;
  924.           mov    ecx,ebx
  925.           and    eax,0fffh
  926.           sub    cl,16
  927.           mov    ax,[_sqrt_table+eax*2]
  928.           sar    cl,1
  929.           js     rtr1
  930.           shl    eax,cl
  931.           pop    ebx
  932.           pop    ecx
  933.           ret
  934.  
  935. rtr1:     neg    cl
  936.           shr    eax,cl
  937.           pop    ebx
  938.           pop    ecx
  939.           ret
  940.  
  941. ffhyp_ endp
  942.  
  943.  
  944.  
  945. public ffalmosthyp_
  946.  
  947. ffalmosthyp_ proc near 
  948.  
  949.          or     eax,eax
  950.          push   edx
  951.          jns    fah_1
  952.          neg    eax
  953.  
  954. fah_1:   or     edx,edx
  955.          jns    fah_2
  956.          neg    edx
  957.  
  958. fah_2:   cmp    eax,edx
  959.          jae    fah_3
  960.          xchg   eax,edx
  961.  
  962. fah_3:   shr    edx,1
  963.          add    eax,edx
  964.          pop    edx
  965.          ret
  966.  
  967. ffalmosthyp_ endp
  968.  
  969.  
  970.  
  971. public ffmuldiv_
  972.  
  973.  
  974. ffmuldiv_ proc near
  975.  
  976.          push    esi
  977.          push    ebx
  978.          push    ecx
  979.  
  980.          push    eax
  981.          push    edx
  982.  
  983.  
  984. ffmd5:   mov     eax,ebx
  985.          imul    ecx
  986.          je      ffmd_zero_nominator
  987.          mov     ebx,eax
  988.          mov     ecx,edx
  989.          mov     eax,[esp]
  990.          mov     edx,[esp+4]
  991.          imul    edx
  992.  
  993.          or      edx,edx
  994.          mov     esi,edx             ; sign of nominator
  995.          jns     ffmd51
  996.          neg     eax                 ; negating denominator
  997.          neg     edx
  998.  
  999. ffmd51:  or      ecx,ecx         
  1000.          jns     ffmd52
  1001.          xor     esi,0x80000000      ; change sign of result
  1002.  
  1003.          not     ebx
  1004.          not     ecx
  1005.  
  1006. ffmd52:  cmp     edx,0xFFFF
  1007.          ja      ffmd520
  1008.          shld    edx,eax,16
  1009.          shl     eax,16
  1010.          or      ecx,ecx
  1011.          jmp     ffmd521
  1012.  
  1013. ffmd520: shrd    ebx,ecx,16        
  1014.          shr     ecx,16
  1015.  
  1016. ffmd521: jne     ffmd_more_shift
  1017.          cmp     edx,ebx
  1018.          jae     ffmd_overflow
  1019.  
  1020.          idiv    ebx                 ; there is no test for overflow
  1021.          or      esi,esi
  1022.          pop     edx                 ; in this division
  1023.          jns     ffmd53
  1024.          neg     eax
  1025.  
  1026. ffmd53:  add     esp,4
  1027.          pop     ecx
  1028.          pop     ebx
  1029.          pop     esi
  1030.          ret
  1031.  
  1032.  
  1033. ffmd_more_shift:
  1034.          shrd    eax,edx,16
  1035.          shr     edx,16
  1036.          shrd    ebx,ecx,16
  1037.          cmp     edx,ebx
  1038.          jae     ffmd_overflow
  1039.          idiv    ebx
  1040.          or      esi,esi
  1041.          pop     edx
  1042.          jns     ffmd54
  1043.          neg     eax
  1044.  
  1045. ffmd54:  add     esp,4
  1046.          pop     ecx
  1047.          pop     ebx
  1048.          pop     esi
  1049.          ret
  1050.  
  1051. ffmd_overflow:
  1052.          pop     edx
  1053.          add     esp,4
  1054.          or      esi,esi
  1055.          js      ffmd6
  1056.          mov     eax,07FFFFFFFh
  1057.          pop     ecx
  1058.          pop     ebx
  1059.          pop     esi
  1060.          ret
  1061.  
  1062. ffmd_zero_nominator:
  1063.          pop     edx
  1064.          pop     eax
  1065.          xor     eax,edx
  1066.          js      ffmd6
  1067.          
  1068.          mov     eax,07FFFFFFFh ; positive infinity
  1069.          pop     ecx
  1070.          pop     ebx
  1071.          pop     esi
  1072.          ret
  1073.  
  1074. ffmd6:   mov     eax,080000000h ; negative infinity
  1075.          pop     ecx
  1076.          pop     ebx
  1077.          pop     esi
  1078.          ret
  1079.  
  1080. ffmuldiv_ endp
  1081.  
  1082.  
  1083. public ffmmd_
  1084. ffmmd_ proc near
  1085.  
  1086.          push    esi
  1087.          push    ebx
  1088.          xor     esi,esi
  1089.          push    edx
  1090.  
  1091. ffmmd2:  imul    edx
  1092.          jns     ffmmd3
  1093.  
  1094.          neg     edx
  1095.          neg     eax
  1096.  
  1097.          inc     esi
  1098.  
  1099. ffmmd3:  or      ebx,ebx
  1100.          jns     ffmmd4
  1101.  
  1102.          neg     ebx
  1103.          dec     esi
  1104.  
  1105. ffmmd4:  cmp     edx,ebx
  1106.          jae     ffmmd_overflow
  1107.          div     ebx
  1108.          or      esi,esi
  1109.          pop     edx
  1110.          je      ffmmd5
  1111.          neg     eax
  1112.  
  1113. ffmmd5:  pop     ebx
  1114.          pop     esi
  1115.          ret
  1116.  
  1117. ffmmd_overflow:
  1118.          or      esi,esi
  1119.          pop     edx
  1120.          pop     ebx
  1121.          pop     esi
  1122.          js      ffmmd6
  1123.          
  1124.          mov     eax,07FFFFFFFh
  1125.          ret
  1126.  
  1127. ffmmd6:  mov     eax,080000000h
  1128.          ret
  1129.  
  1130.  
  1131. ffmmd_ endp
  1132.  
  1133.  
  1134.  
  1135. public ffortproj_
  1136.  
  1137. ; eax - a
  1138. ; edx - b
  1139. ; ebx - c
  1140. ; ecx - d
  1141.  
  1142. ; returns (a*b+c*d)/(a*a+c*c)
  1143.  
  1144. ffortproj_ proc near
  1145.  
  1146.          push   ebx
  1147.          push   edx
  1148.          push   ecx
  1149.  
  1150.          sar    eax,5
  1151.          sar    edx,5
  1152.          sar    ebx,5
  1153.          sar    ecx,5
  1154.          push   eax
  1155.  
  1156.          call   ffsmul_  ; eax = a*b
  1157.          push   eax
  1158.  
  1159.          mov    eax,ebx
  1160.          mov    edx,ecx
  1161.          call   ffsmul_  ; eax = c*d
  1162.  
  1163.          pop    ecx     ; ecx = a*b
  1164.          add    ecx,eax ; ecx = a*b + c*d
  1165.  
  1166.          mov    eax,ebx
  1167.          mov    edx,ebx
  1168.          call   ffsmul_
  1169.          mov    ebx,eax ; ebx = c*c
  1170.  
  1171.          pop    eax
  1172.          mov    edx,eax
  1173.          call   ffsmul_  ; eax = a*a
  1174.  
  1175.          add    ebx,eax ; ebx = c*c + a*a
  1176.          mov    eax,ecx
  1177.          mov    edx,ebx
  1178.          call   ffsdiv_
  1179.  
  1180.          pop    ecx
  1181.          pop    edx
  1182.          pop    ebx
  1183.  
  1184.          ret
  1185.  
  1186. ffortproj_ endp
  1187.  
  1188.  
  1189. public ffortproj1_
  1190.  
  1191. ; eax - a
  1192. ; edx - b
  1193. ; ebx - c
  1194. ; ecx - d
  1195.  
  1196. ; returns (a*b+c*d)/sqrt(a*a+c*c)
  1197.  
  1198. ffortproj1_ proc near
  1199.  
  1200.          push   ebx
  1201.          push   edx
  1202.          push   ecx
  1203.  
  1204.          sar    eax,6
  1205.          sar    edx,6
  1206.          sar    ebx,6
  1207.          sar    ecx,6
  1208.          push   eax
  1209.  
  1210.          call   ffsmul_  ; eax = a*b
  1211.          push   eax
  1212.  
  1213.          mov    eax,ebx
  1214.          mov    edx,ecx
  1215.          call   ffsmul_  ; eax = c*d
  1216.  
  1217.          pop    ecx     ; ecx = a*b
  1218.          add    ecx,eax ; ecx = a*b + c*d
  1219.  
  1220.          mov    eax,ebx
  1221.          mov    edx,ebx
  1222.          call   ffsmul_
  1223.          mov    ebx,eax ; ebx = c*c
  1224.  
  1225.          pop    eax
  1226.          mov    edx,eax
  1227.          call   ffsmul_  ; eax = a*a
  1228.  
  1229.          add    eax,ebx ; ebx = c*c + a*a
  1230.          call   ffsqrt_ ; root it
  1231.  
  1232.          mov    edx,eax
  1233.          mov    eax,ecx
  1234.  
  1235.          call   ffsdiv_
  1236.          shl    eax,6   ; compensating root
  1237.  
  1238.          pop    ecx
  1239.          pop    edx
  1240.          pop    ebx
  1241.  
  1242.          ret
  1243.  
  1244. ffortproj1_ endp
  1245.  
  1246. public ffdot_through_hyps_
  1247.  
  1248. ; eax - a
  1249. ; edx - b
  1250. ; ebx - c
  1251. ; ecx - d
  1252.  
  1253. ; returns (a*b+c*d)/(sqrt(a*a+c*c)*sqrt(b*b+d*d))
  1254.  
  1255. ffdot_through_hyps_ proc near
  1256.  
  1257.          push   ebx
  1258.          push   edx
  1259.          push   ecx
  1260.  
  1261.          sar    eax,5
  1262.          sar    edx,5
  1263.          sar    ebx,5
  1264.          sar    ecx,5
  1265.  
  1266.          push   edx
  1267.          push   ecx
  1268.          push   eax
  1269.  
  1270.          call   ffsmul_  ; eax = a*b
  1271.          push   eax
  1272.  
  1273.          mov    eax,ebx
  1274.          mov    edx,ecx
  1275.          call   ffsmul_  ; eax = c*d
  1276.  
  1277.          pop    ecx     ; ecx = a*b
  1278.          add    ecx,eax ; ecx = a*b + c*d
  1279.  
  1280.          mov    eax,ebx
  1281.          mov    edx,ebx
  1282.          call   ffsmul_
  1283.          mov    ebx,eax ; ebx = c*c
  1284.  
  1285.          pop    eax
  1286.          mov    edx,eax
  1287.          call   ffsmul_  ; eax = a*a
  1288.  
  1289.          add    eax,ebx
  1290.          call   ffsqrt_
  1291.          mov    ebx,eax  ; ebx = sqrt(c*c + a*a)
  1292.  
  1293.          pop    eax
  1294.          mov    edx,eax
  1295.          call   ffsmul_  ; eax = d*d
  1296.  
  1297.          pop    edx
  1298.          push   eax
  1299.          mov    eax,edx
  1300.          call   ffsmul_  ; eax = b*b
  1301.  
  1302.          pop    edx
  1303.          add    eax,edx
  1304.          call   ffsqrt_  ; eax = sqrt(d*d + b*b)
  1305.  
  1306.          mov    edx,ebx
  1307.          call   ffmul_   ; eax = sqrt(d*d + b*b) * sqrt(c*c + a*a)
  1308.  
  1309.          mov    edx,eax
  1310.          mov    eax,ecx
  1311.          call   ffsdiv_  ; eax = a*b + c*d / (sqrt(d*d + b*b) * sqrt(c*c + a*a))
  1312.  
  1313.          pop    ecx
  1314.          pop    edx
  1315.          pop    ebx
  1316.  
  1317.          ret
  1318.  
  1319. ffdot_through_hyps_ endp
  1320.  
  1321.  
  1322. public isqrt_
  1323.  
  1324. isqrt_  proc near
  1325.  
  1326.    push     ecx
  1327.    push     edx
  1328.    push     eax
  1329.  
  1330. ;   bsr      ecx,eax   ; unfold
  1331.  
  1332. ; code from here
  1333.  
  1334.           xor    ecx,ecx
  1335.           cmp    eax,010000h
  1336.           jb     is30
  1337.           shr    eax,16
  1338.           add    cl,16
  1339.  
  1340. is30:     cmp    eax,0100h
  1341.           jb     is31
  1342.           shr    eax,8
  1343.           add    cl,8
  1344.  
  1345. is31:     cmp    eax,010h
  1346.           jb     is32
  1347.           shr    eax,4
  1348.           add    cl,4
  1349.  
  1350. is32:     cmp    eax,04h
  1351.           jb     is33
  1352.           shr    eax,2
  1353.           add    cl,2
  1354.  
  1355. is33:     cmp    eax,2
  1356.           jb     is34
  1357.           inc    ecx
  1358.  
  1359. is34:
  1360. ; to here replaces bsr with a factor 2.5 speed gain
  1361.  
  1362.    mov      edx,ecx
  1363.    sub      cl,10
  1364.    neg      edx
  1365.    test     cl,1
  1366.    pop      eax
  1367.    je       is1
  1368.  
  1369.    inc      edx
  1370.    dec      ecx
  1371. is1:
  1372.    add      dl,31
  1373.    or       cl,cl
  1374.    js       is2
  1375.    shr      eax,cl
  1376.    jmp      is3
  1377.  
  1378. is2:
  1379.    neg      cl
  1380.    shl      eax,cl
  1381.  
  1382. is3:
  1383.    shr      dl,1
  1384.    mov      ax,[_sqrt_table+eax*2]
  1385.    mov      ecx,edx
  1386.    pop      edx
  1387.    shr      eax,cl
  1388.    pop      ecx
  1389.    ret
  1390.  
  1391. isqrt_ endp
  1392.  
  1393.  
  1394.  
  1395. ; eax  -  denominator lo part
  1396. ; edx  -  denominator hi
  1397. ; ebx  -  nominator
  1398. ; ecx  -  pointer to DWORD location to store 
  1399. ;         decimal fraction of result.
  1400.  
  1401. ; returns the integer part of result
  1402. ; works with signed 64 bit quantities
  1403. ; this routine does not check for any zero divisions
  1404.  
  1405.  
  1406. public ff_double_div_
  1407.  
  1408. ff_double_div_  proc near
  1409.  
  1410.             push    edx
  1411.             push    edi
  1412.  
  1413.             xor     edi,edi
  1414.             or      edx,edx
  1415.             jns     dd_1
  1416.  
  1417.             neg     edx
  1418.             neg     eax          ; make both numbers positive
  1419.             sbb     edx,0
  1420.             inc     edi
  1421.  
  1422. dd_1:       or      ebx,ebx
  1423.             jns     dd_2
  1424.             neg     ebx
  1425.             inc     edi
  1426.  
  1427. dd_2:       div     ebx
  1428.             push    eax          ; this is integer part of 
  1429.                                  ; division
  1430.  
  1431.             xor     eax,eax      ; produce decimal part of
  1432.             div     ebx          ; division
  1433.  
  1434.             pop     edx          ; eax - decpart, edx - intpart
  1435.  
  1436. dd_4:       test    edi,1
  1437.             je      dd_5
  1438.  
  1439.             neg     edx          ; negate integer part
  1440.             neg     eax          ; negate decimal part
  1441.             sbb     edx,0        ; dec if non zero eax
  1442.  
  1443. dd_5:       mov     [ecx],eax    ; store away decimal fraction
  1444.             mov     eax,edx      ; return integer fraction
  1445.             
  1446. dd_restore_reg:
  1447.             pop     edi          ; restore registers
  1448.             pop     edx
  1449.  
  1450.             ret
  1451.  
  1452. ff_double_div_  endp
  1453.  
  1454. ;
  1455. ; eax - pointer to low value
  1456. ; edx - pointer to hi value
  1457. ; ebx - 0    - ordinary shift
  1458. ;       no 0 - arithmetic shift
  1459. ; ecx - nr of steps to shift,
  1460. ;       right is positive,
  1461. ;       left is negative
  1462. ;
  1463.  
  1464. public ff_double_shift_
  1465.  
  1466. ff_double_shift_ proc near
  1467.  
  1468.             push      esi
  1469.             or        ecx,ecx
  1470.             js        dr_left
  1471.  
  1472.             ; rotate right
  1473.             mov       esi,[edx]
  1474.             shrd      [eax],esi,cl
  1475.             xor       esi,esi
  1476.             or        ebx,ebx
  1477.             jne       dr_aritm
  1478.             
  1479.             shrd      [edx],esi,cl
  1480.             pop       esi
  1481.             ret
  1482.  
  1483. dr_aritm:   mov       esi,[edx]
  1484.             sar       esi,31
  1485.             shrd      [edx],esi,cl
  1486.             pop       esi
  1487.             ret
  1488.  
  1489.             ; shift left
  1490. dr_left:    push      ecx
  1491.             neg       ecx
  1492.             mov       esi,[eax]
  1493.             shld      [edx],esi,cl
  1494.             xor       esi,esi
  1495.             shld      [eax],esi,cl            
  1496.             pop       ecx
  1497.             pop       esi
  1498.             ret
  1499.  
  1500. ff_double_shift_ endp                   
  1501. ;                                              /\  Y
  1502. ;                                               |                                                
  1503. ; This routine takes a                          |   o (1,2)    
  1504. ; vector in it's rectangular form               |  /
  1505. ; and returns the angle it forms                | /\  V = atan(2/1)
  1506. ; in relation to the point (1,0).               |/  |
  1507. ; that is coordinate (0,1) will return          -------------> X
  1508. ; (90/360)*65536 ,
  1509. ; coordinate (0,-1) will return 
  1510. ; ((-90/360)*65536) & 65535
  1511. ;
  1512. ; renember, there are 65536 degrees in
  1513. ; a circle in fixfloat universe.
  1514.  
  1515.  
  1516. ; eax - x component
  1517. ; edx - y component
  1518.  
  1519. ; returns result in eax
  1520.  
  1521. public ff_vec_to_ang_
  1522.  
  1523. ff_vec_to_ang_ proc near
  1524.   
  1525.         or      eax,eax
  1526.         push    edx
  1527.         push    ecx
  1528.         mov     cl,0
  1529.         js      ff_fta0
  1530.         
  1531.         jne     ff_fta1
  1532.         or      edx,edx
  1533.         je      ff_zero_vector
  1534.         jmp     ff_fta1
  1535.  
  1536. ff_fta0:        
  1537.         neg     eax             ; make sure x component is positive
  1538.         neg     edx
  1539.         inc     cl              ; flag that we have to subtract/add '180' degrees to angle
  1540.         
  1541. ff_fta1:
  1542.         cmp     edx,eax         ; test if y>x
  1543.         jge     ff_y_bigger
  1544.         push    edx             
  1545.         neg     edx
  1546.         cmp     edx,eax         ; test if -y>x
  1547.         pop     edx
  1548.         jge     ff_y_bigger
  1549.                                 ; abs(x)>abs(y)
  1550.         xchg    eax,edx         ; put y on top in divisor, x in bottom
  1551.         call    ffsdiv_         ; divide
  1552.         call    ffatan_         ; arc tan
  1553.         jmp     ff_fta2
  1554.         
  1555. ff_y_bigger:                    ; abs(y)>abs(x)
  1556.         push    0004000h
  1557.         or      edx,edx
  1558.         jns     ff_yb1
  1559.         mov     DWORD PTR[esp],000c000h
  1560.         
  1561. ff_yb1: call    ffsdiv_
  1562.         call    ffatan_
  1563.         neg     eax
  1564.         pop     edx
  1565.         add     eax,edx
  1566.         
  1567. ff_fta2:
  1568.         or      cl,cl           ; see if need to flip angle '180' degrees
  1569.         pop     ecx
  1570.         je      ff_fta3
  1571.         
  1572.         xor     eax,08000h      ; flip it
  1573.         
  1574. ff_fta3:        
  1575.         and     eax,0FFFFh
  1576.         pop     edx
  1577.         ret
  1578.         
  1579. ff_zero_vector:
  1580.         xor     eax,eax
  1581.         pop     ecx
  1582.         pop     edx
  1583.         ret
  1584.         
  1585. ff_vec_to_ang_ endp                
  1586.                             
  1587.  
  1588. ; this routine solves a 2:nd degree equation
  1589. ; by std formula, for given p & 1 :
  1590. ;
  1591. ;  2
  1592. ; x  + px + q = 0
  1593. ;                           
  1594. ; setup at call :
  1595. ; eax - p
  1596. ; edx - q
  1597. ; ebx - pointer to where to put conjugate part ( the +/- term )
  1598. ; ecx - pointer to where to put prefix part (-p/2)
  1599. ;
  1600. ; returns eax - 0      if solved OK
  1601. ; returns eax - no 0   if no real roots
  1602. ; routine handles cases where p*p/4-q>32767 correctly, 
  1603. ; since it uses intermediate 64 bit representation
  1604. ;
  1605.  
  1606. public ff_solve_2nd_poly_ 
  1607.  
  1608. ff_solve_2nd_poly_ proc near
  1609.  
  1610.         push    edx
  1611.         push    ecx
  1612.         push    eax
  1613.         
  1614.         mov     ecx,edx                 ; square the p term
  1615.         mov     edx,eax
  1616.         imul    edx
  1617.         shrd    eax,edx,18              ; work with 64 bits for a while
  1618.         sar     edx,18
  1619.         or      ecx,ecx                 ; slightly different behaviour if negative q value
  1620.         js      ff2nd_1
  1621.         
  1622.         sub     eax,ecx
  1623.         sbb     edx,0
  1624.         jmp     ff2nd_2
  1625.         
  1626. ff2nd_1:
  1627.         neg     ecx
  1628.         add     eax,ecx
  1629.         adc     edx,0
  1630.         
  1631. ff2nd_2:
  1632.         js      ff2nd_no_real_roots     ; such things happens...
  1633.         xor     ecx,ecx
  1634.         or      edx,edx
  1635.         je      ff2nd_4
  1636.  
  1637. ff2nd_3:
  1638.         shrd    eax,edx,2               ; enable momentary overflow but still give correct result
  1639.         inc     ecx                     ; with the help of afew shifts
  1640.         shr     edx,2
  1641.         jne     ff2nd_3
  1642.         
  1643. ff2nd_4:
  1644.         call    ffsqrt_
  1645.         shl     eax,cl
  1646.         mov     [ebx],eax               ; storing conjugate
  1647.         
  1648.         pop     eax
  1649.         pop     ecx
  1650.         neg     eax                     ; calc -p/2
  1651.         pop     edx
  1652.         sar     eax,1
  1653.         mov     [ecx],eax
  1654.         xor     eax,eax                 ; indicate we did OK
  1655.         ret
  1656.         
  1657. ff2nd_no_real_roots:
  1658.         pop     eax
  1659.         pop     ecx
  1660.         neg     eax
  1661.         pop     edx
  1662.         sar     eax,1
  1663.         mov     [ecx],eax
  1664.         mov     al,1                    ; indicate no real roots
  1665.         ret
  1666.         
  1667. ff_solve_2nd_poly_ endp
  1668.                 
  1669. _TEXT   ENDS
  1670.     END
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.